In [1]:
%pylab inline


Populating the interactive namespace from numpy and matplotlib

Requirements

In the case of Ericsson MINK LINK Traffic Node system one has to provide the following information to query data via SNMP:

  • IP adress
  • slot number
  • from which end to query, far_end or near_end

Read in link metadata (IP, slot, location, etc...) from XLS file

Below is a specific parser for the XLS files we get from Ericsson and will not be oh help for you since your may most likely get the metadata in a very different format. But I have to read our data in to demostrate how to build the OID listing

Please note, that our metadata XLS file lists the slot information of 1+1 protection systems as e.g. '2+3', if slot 2 and 3 of a certain system (with the same IP) belong to the same 1+1 system. This is resolved in the functions below and two system are built for the SNMP requests. We later on put the back together when we process the raw data.


In [2]:
from ifu_comlink_database.parser.ericsson import read_xls_file_site_info, read_xls_file_link_info

In [3]:
fn = '/Users/chwala-c/code/ifu_comlink_database/ifu_comlink_database/link_lists/Procema_2015_04_22.xlsx'

link_dict = read_xls_file_link_info(fn)
site_dict = read_xls_file_site_info(fn)

As an example the first link in the list


In [4]:
for key in ['a_site', 'a_ip', 'a_slot', 'b_site', 'b_ip', 'b_slot']:
    print key, link_dict[key][0]


a_site MY0094
a_ip 10.31.64.24
a_slot 2.0
b_site MY2108
b_ip 10.31.64.20
b_slot 3.0

Functions to build link OID dict list

Function to derive slots from entry in link_dict


In [5]:
def get_slot_list(slot_number_or_str):
    """
    Derive a list of slot numbers from XLS file entry
    
    Parameters
    ----------
    
    slot_number_or_str : int, float or unicode str
        Representation of slot or slots in XLS list. Unicode 
        string are used for the 1+1 protection systems.
        
    Returns
    -------
    
    slot_list : list
        List of slots. Even for only one slot a list is returned!   
    
    """
    
    if type(slot_number_or_str) == float:
        slot_list = [int(slot_number_or_str),]
    elif type(slot_number_or_str) == int:
        slot_list = [int(slot_number_or_str),]
    elif type(slot_number_or_str) == unicode:
        if slot_number_or_str == u'2+3 (1+1)':
            slot_list = [2,3]
        elif slot_number_or_str == u'3+4 (1+1)':
            slot_list = [3,4]
        elif slot_number_or_str == u'4+5 (1+1)':
            slot_list = [4,5]
        else:
            raise ValueError('slot_number_of_string string not understood')
    else:
        raise ValueError('slot_number_of_string must be int, float or unicode')
    return slot_list

In [6]:
def build_TN_interface_descriptor(slot, near_far):
    """ 
    Calculate the interface descriptor for TN MW links
    
    Parameters
    ----------
    
    slot : int
        Slot number
    near_far : str
        String to indicate which end of the link is the aim.
        Options are: `near`, `far` and `far_protect`
    
    Returns
    -------
    
    str
        String of interface descriptor, e.g. 
        2146697601 for slot 3 at near_end
        
    """
    
    # This are the values for slot 2, that do not have to be altered
    if near_far=='near':
        hex_base = '0x7ff40101'
    elif near_far=='far':
        hex_base = '0x7ef40101'
    elif near_far=='far_protect':
        hex_base = '0x7df40101'
    else:
        raise ValueError("near_far can only be 'near', 'far' or 'far_protect'")
    # Add 128 for each slot greater than 2 and return as string of an int
    return str(int(hex_base,16) + 128*(int(slot)-2))

def build_TN_OID(cmd, slot, near_far):
    """
    Build OIDs from a certain SNMP query command
    
       Parameters
    ----------
    
    cmd : str
        Command for SNMP request. Right now only `RX` and `TX` are supported
    slot : int
        Slot number
      near_far : str
        String to indicate which end of the link is the aim.
        Options are: `near`, `far` and `far_protect`
            
    Returns
    -------
    
    str
        OID as a string starting with a `.`, e.g. 
        .1.3.6.1.4.1.193.81.3.4.3.1.3.1.10.2146697601
        for `RX` level at slot 3 at near_end
    
    """
    
    OIDS = {}
    OIDS['TX'] = '.1.3.6.1.4.1.193.81.3.4.3.1.3.1.1'
    OIDS['RX'] = '.1.3.6.1.4.1.193.81.3.4.3.1.3.1.10'
    # Return OID plus interface_descriptor for slot and near or far end
    return OIDS[cmd] + '.' + build_TN_interface_descriptor(slot, near_far)

Test the function for building the interface desciptor


In [7]:
print int(build_TN_interface_descriptor(2, 'near'))
print int(build_TN_interface_descriptor(3, 'near'))
print int(build_TN_interface_descriptor(4, 'near'))

print hex(int(build_TN_interface_descriptor(2, 'near')))
print hex(int(build_TN_interface_descriptor(3, 'near')))
print hex(int(build_TN_interface_descriptor(4, 'near')))

print bin(int(build_TN_interface_descriptor(2, 'near')))
print bin(int(build_TN_interface_descriptor(3, 'near')))
print bin(int(build_TN_interface_descriptor(4, 'near')))


2146697473
2146697601
2146697729
0x7ff40101
0x7ff40181
0x7ff40201
0b1111111111101000000000100000001
0b1111111111101000000000110000001
0b1111111111101000000001000000001

Test the function to build OID


In [8]:
for slot in range(2,6):
    print ''
    for nf in ['near', 'far', 'far_protect']:
        print slot, nf, build_TN_OID('RX', slot, nf)


2 near .1.3.6.1.4.1.193.81.3.4.3.1.3.1.10.2146697473
2 far .1.3.6.1.4.1.193.81.3.4.3.1.3.1.10.2129920257
2 far_protect .1.3.6.1.4.1.193.81.3.4.3.1.3.1.10.2113143041

3 near .1.3.6.1.4.1.193.81.3.4.3.1.3.1.10.2146697601
3 far .1.3.6.1.4.1.193.81.3.4.3.1.3.1.10.2129920385
3 far_protect .1.3.6.1.4.1.193.81.3.4.3.1.3.1.10.2113143169

4 near .1.3.6.1.4.1.193.81.3.4.3.1.3.1.10.2146697729
4 far .1.3.6.1.4.1.193.81.3.4.3.1.3.1.10.2129920513
4 far_protect .1.3.6.1.4.1.193.81.3.4.3.1.3.1.10.2113143297

5 near .1.3.6.1.4.1.193.81.3.4.3.1.3.1.10.2146697857
5 far .1.3.6.1.4.1.193.81.3.4.3.1.3.1.10.2129920641
5 far_protect .1.3.6.1.4.1.193.81.3.4.3.1.3.1.10.2113143425

Build a OID dict list to query RX- and TX-levels from far_end and near_end

The format (list of dictonaries with the specific keys) is the the format pySNMPdaq expects


In [9]:
link_list = []
OID_list = ['TX', 'RX']

for i in range(len(link_dict['a_slot'])):
    # Get ID, Slots and IP
    a_id = link_dict['a_site'][i]
    b_id = link_dict['b_site'][i]
    a_slot_list = get_slot_list(link_dict['a_slot'][i])
    b_slot_list = get_slot_list(link_dict['b_slot'][i])
    ip = link_dict['a_ip'][i]
    
    # Check if near end uses a 1+1 protection (i.e. two slots are used) 
    if len(a_slot_list) == 1:
        protection_near = False
    elif len(a_slot_list) == 2:
        protection_near = True
    else:
        raise ValueError('There should only be 1 or 2 slots for site A')
    # Check if far end uses 1+1 protection
    if len(b_slot_list) == 1:
        protection_far = False
    elif len(b_slot_list) == 2:
        protection_far = True
    else:
        raise ValueError('There should only be 1 or 2 slots for site B')
        
    # Build OID dict and append to link_list together with metadata
    for a_slot in a_slot_list:
        for i_b_slot, b_slot in enumerate(b_slot_list):
            link_id = a_id + '_' + str(a_slot) + '_' + b_id + '_' + str(b_slot)
            OID_dict = {}
            # Build OID dict and distinguish between far end with and without 1+1 protection.
            # (This is not necessary for near end.)
            for far_near in ['far', 'near']:
                # Adjust OID for far end protection
                for OID in OID_list:
                    if i_b_slot == 0:
                        TN_OID = build_TN_OID(OID, a_slot, far_near)
                    elif i_b_slot == 1 and far_near == 'near':
                        TN_OID = build_TN_OID(OID, a_slot, 'near')
                    elif i_b_slot == 1 and far_near == 'far':
                        TN_OID = build_TN_OID(OID, a_slot, 'far_protect')
                    else:
                        raise ValueError('There seem to be more than two \
                                         slots for far end. This is not supported.')
                    OID_dict[OID + '_' + far_near] = TN_OID
            # Append to link_list
            link_list.append({'ID': link_id,
                              'IP' : ip,
                              'protection_near': protection_near,
                              'protection_far': protection_far,
                              'slot_near': a_slot,
                              'slot_far': b_slot,
                              'OID_dict': OID_dict})

Show the first entries of the OID dict list


In [10]:
link_list[0:3]


Out[10]:
[{'ID': u'MY0094_2_MY2108_3',
  'IP': u'10.31.64.24',
  'OID_dict': {'RX_far': '.1.3.6.1.4.1.193.81.3.4.3.1.3.1.10.2129920257',
   'RX_near': '.1.3.6.1.4.1.193.81.3.4.3.1.3.1.10.2146697473',
   'TX_far': '.1.3.6.1.4.1.193.81.3.4.3.1.3.1.1.2129920257',
   'TX_near': '.1.3.6.1.4.1.193.81.3.4.3.1.3.1.1.2146697473'},
  'protection_far': False,
  'protection_near': False,
  'slot_far': 3,
  'slot_near': 2},
 {'ID': u'MY0518_2_MY2033_2',
  'IP': u'10.30.64.8',
  'OID_dict': {'RX_far': '.1.3.6.1.4.1.193.81.3.4.3.1.3.1.10.2129920257',
   'RX_near': '.1.3.6.1.4.1.193.81.3.4.3.1.3.1.10.2146697473',
   'TX_far': '.1.3.6.1.4.1.193.81.3.4.3.1.3.1.1.2129920257',
   'TX_near': '.1.3.6.1.4.1.193.81.3.4.3.1.3.1.1.2146697473'},
  'protection_far': False,
  'protection_near': False,
  'slot_far': 2,
  'slot_near': 2},
 {'ID': u'MY0207_2_MY2248_2',
  'IP': u'10.30.64.56',
  'OID_dict': {'RX_far': '.1.3.6.1.4.1.193.81.3.4.3.1.3.1.10.2129920257',
   'RX_near': '.1.3.6.1.4.1.193.81.3.4.3.1.3.1.10.2146697473',
   'TX_far': '.1.3.6.1.4.1.193.81.3.4.3.1.3.1.1.2129920257',
   'TX_near': '.1.3.6.1.4.1.193.81.3.4.3.1.3.1.1.2146697473'},
  'protection_far': False,
  'protection_near': False,
  'slot_far': 2,
  'slot_near': 2}]

Dump the OID dict list to a file so that pySNMPdaq can read it in


In [11]:
import pprint

f = open('link_list.py','w')
pprint.pprint(link_list, f)
f.close()